﻿using Kingdee.BOS;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.Bill;
using Kingdee.BOS.Core.Bill.PlugIn;
using Kingdee.BOS.Core.CommonFilter;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.DynamicForm.PlugIn.ControlModel;
using Kingdee.BOS.Core.FieldReader;
using Kingdee.BOS.Core.List;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.Core.Metadata.FieldElement;
using Kingdee.BOS.Core.Metadata.FormElement;
using Kingdee.BOS.Core.Metadata.PreInsertData;
using Kingdee.BOS.Core.Metadata.Util;
using Kingdee.BOS.Core.NotePrint;
using Kingdee.BOS.Core.Permission;
using Kingdee.BOS.Core.Report;
using Kingdee.BOS.Core.SqlBuilder;
using Kingdee.BOS.JSON;
using Kingdee.BOS.Model.ReportFilter;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Resource;
using Kingdee.BOS.Serialization;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using Kingdee.BOS.Web;
using Kingdee.BOS.Web.Report;
using LianKe.BaseData;
using LianKe.LianKeSchedule;
using Newtonsoft.Json;
using OfficeOpenXml;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
//using System.Runtime.Remoting.Contexts;
using System.Text;
using System.Threading.Tasks;
using System.Web.UI.WebControls;
using System.Xml.Serialization;
using static LianKe.BaseData.BaseParam;

namespace LianKe.FormPlugIn
{
    [Description("联科方案配置插件"), HotUpdate]
    public class ExtPlugIn : AbstractDynamicFormPlugIn
    {

        public override void BarItemClick(BarItemClickEventArgs e)
        {
            base.BarItemClick(e);
            var obj = this.Model.DataObject;
            string scheduleName = GetScheduleName(obj);
            string fileName = this.Model.DataObject["F_DateStr"].GetString();
            var F_DateList = this.Model.DataObject["F_DateList"].ToString();
            StartDate strAndEndDate = GetDateList(F_DateList);
            if (e.BarItemKey.Equals("POSW_CreateSchedule"))
            {
                string fstatus = obj["DocumentStatus"].ToString();
                if (!fstatus.ToUpper().Equals("C"))
                {
                    this.View.ShowErrMessage($"单据未审核，不允许生成执行计划!", "状态检验", MessageBoxType.Error);
                    return;
                }
                IBillView view = CreateBillView(this.Context, "BOS_SCHEDULETYPE");
                bool isHaveSchedule = CheckSchedule(scheduleName, view);
                if (!isHaveSchedule)
                {
                    this.View.ShowErrMessage($"名称为：{scheduleName}的执行计划已经存存，不需重复创建!", "名称重复", MessageBoxType.Error);
                    return;
                }
                bool isCreate = AddSchedule(scheduleName, obj, view, strAndEndDate, fileName);
            }
            if (e.BarItemKey.Equals("POSW_tbButtonTest"))
            {
                //参数
                var parm = GetParametersObj(this.Model.DataObject, scheduleName, strAndEndDate, fileName);
                foreach (var mail in parm.To)
                {
                    TestSendMail(fileName, strAndEndDate, mail, parm);
                }
            }
        }

        private StartDate GetDateList(string f_DateList)
        {
            // 获取本月范围
            DateTime today = DateTime.Today;
            DateTime firstDayThisMonth = new DateTime(today.Year, today.Month, 1);
            DateTime lastDayThisMonth = firstDayThisMonth.AddMonths(1).AddDays(-1);

            // 获取上月范围
            DateTime firstDayLastMonth = firstDayThisMonth.AddMonths(-1);
            DateTime lastDayLastMonth = firstDayLastMonth.AddMonths(1).AddDays(-1);

            // 本年范围
            DateTime firstDayThisYear = new DateTime(today.Year, 1, 1);
            DateTime lastDayThisYear = new DateTime(today.Year, 12, 31);

            // 上年范围
            DateTime firstDayLastYear = new DateTime(today.Year - 1, 1, 1);
            DateTime lastDayLastYear = new DateTime(today.Year - 1, 12, 31);

            // 计算本周范围（周一至周日）
            int daysSinceMonday = ((int)today.DayOfWeek - (int)DayOfWeek.Monday + 7) % 7;
            DateTime firstDayOfThisWeek = today.AddDays(-daysSinceMonday);
            DateTime lastDayOfThisWeek = firstDayOfThisWeek.AddDays(6);

            // 计算上周范围
            DateTime firstDayOfLastWeek = firstDayOfThisWeek.AddDays(-7);
            DateTime lastDayOfLastWeek = lastDayOfThisWeek.AddDays(-7);

            StartDate date = new StartDate();
            switch (f_DateList)
            {
                case "0":
                    date.StrDate = today;
                    date.EndDate = today;
                    break;
                case "1":
                    date.StrDate = today.AddDays(-1);
                    date.EndDate = today.AddDays(-1);
                    break;
                case "2":
                    date.StrDate = firstDayOfThisWeek;
                    date.EndDate = lastDayOfThisWeek;
                    break;
                case "3":
                    date.StrDate = firstDayOfLastWeek;
                    date.EndDate = lastDayOfLastWeek;
                    break;
                case "4":
                    date.StrDate = firstDayThisYear;
                    date.EndDate = lastDayThisYear;
                    break;
                case "5":
                    date.StrDate = firstDayLastYear;
                    date.EndDate = lastDayLastYear;
                    break;
                case "6":
                    date.StrDate = firstDayThisMonth;
                    date.EndDate = lastDayThisMonth;
                    break;
                case "7":
                    date.StrDate = firstDayLastMonth;
                    date.EndDate = lastDayLastMonth;
                    break;
            }
            return date;
        }

        private void TestSendMail(string f_DateStr, StartDate strAndEndDate, string mail, ScheduleParameter parameter)
        {
            string rptFilterSchemeId = parameter.SchemeId;
            DynamicObject obj = this.Model.DataObject["F_POSW_YWDX"] as DynamicObject;
            string rptFormId = obj["id"].ToString(); //查询的目标报表标识
            var rptMetadata = FormMetaDataCache.GetCachedFormMetaData(this.Context, rptFormId);
            var comFilterMetadata = FormMetaDataCache.GetCachedFilterMetaData(this.Context);
            //var rptMetadata = FormMetaDataCache.GetCachedFormMetaData(ctx, rptFormId);
            var rptFilterMetadata = FormMetaDataCache.GetCachedFormMetaData(this.Context, parameter.RptFilterFormId);
            var rptType = rptMetadata.BaseObjectId;
            if (rptType == "BOS_SQLReport")
            {
                var sqlDt = GetSqlRptData(this.Context, rptMetadata, f_DateStr, strAndEndDate, rptFilterSchemeId);
                // 生成 Excel 字节流
                byte[] excelBytes = DataTableToExcel(sqlDt);
                // 发送邮件
                SendEmailWithAttachment(excelBytes, mail);
            }
            else if (rptType == "BOS_MoveSysReport")
            {
                var reportFilterServiceProvider = rptFilterMetadata.BusinessInfo.GetForm().GetFormServiceProvider();
                var model = new SysReportFilterModel();
                model.SetContext(this.Context, rptFilterMetadata.BusinessInfo, reportFilterServiceProvider);
                model.FormId = rptFilterMetadata.BusinessInfo.GetForm().Id;
                model.FilterObject.FilterMetaData = comFilterMetadata;
                model.InitFieldList(rptMetadata, rptFilterMetadata);
                model.GetSchemeList();//过滤方案的主键值，可通过该SQL语句查询得到：SELECT * FROM T_BAS_FILTERSCHEME
                var entity = model.Load(rptFilterSchemeId);
                var dyn = DeserializeCustomFilter(rptFilterMetadata.BusinessInfo, entity.CustomFilterSetting);
                model.DataObject = dyn;
                var filter = model.GetFilterParameter();
                IRptParams rptParam = new RptParams();
                rptParam.FormId = rptFilterMetadata.BusinessInfo.GetForm().Id;
                rptParam.CurrentPosition = 0;//分页账表当前位置
                rptParam.StartRow = 1;
                rptParam.EndRow = int.MaxValue;//StartRow和EndRow是报表数据分页的起始行数和截至行数，一般取所有数据，所以EndRow取int最大值。
                rptParam.FilterParameter = filter;
                rptParam.FilterFieldInfo = model.FilterFieldInfo;
                var dic = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
                foreach (var itemProp in dyn.DynamicObjectType.Properties)
                {
                    dic[itemProp.Name] = dyn[itemProp.Name];
                }
                rptParam.CustomParams.Add("OpenParameter", dic);
                MoveReportServiceParameter param = new MoveReportServiceParameter(this.Context, rptMetadata.BusinessInfo, Guid.NewGuid().ToString(), rptParam);
                var movReport = SysReportServiceHelper.GetListAndReportData(param);
                // rpt.DataSource 获取账表的DataTable
                Dictionary<int, IMoveReport> rtnDIc = new Dictionary<int, IMoveReport>();
                rtnDIc[0] = movReport;
                // 获取其他分页
                if (movReport.ListCount > 1)
                {
                    for (int i = 1; i < movReport.ListCount; i++)
                    {
                        IMoveReport tmpRpt = GetReportDataNext(this.Context, i, rptMetadata.BusinessInfo, rptParam);
                        rtnDIc[i] = tmpRpt;
                    }
                }
                List<BaseDataField> baseDataFields = new List<BaseDataField>();
                List<DateField> dateFields = new List<DateField>();
                List<ComboField> comboFields = new List<ComboField>();
                var typeList = rptMetadata.BusinessInfo.Elements;
                foreach (var type in typeList)
                {
                    var item = type.GetType();
                    var itemName = type.Name;
                    var itemKey = type.Key;
                    var typeName = item.Name;
                    if (typeName.Equals("BaseDataField"))
                    {
                        baseDataFields.Add(type as BaseDataField);
                    }
                    if (typeName.Equals("DateField"))
                    {
                        dateFields.Add(type as DateField);
                    }
                    if (typeName.Equals("ComboField"))
                    {
                        comboFields.Add(type as ComboField);
                    }
                }
                foreach (var rtItem in rtnDIc.Values)
                {
                    var dataf = rtItem.DataSource;
                    var rh = rptParam.FilterParameter.ColumnInfo;
                    List<string> colList = new List<string>();
                    DataTable newDt = new DataTable();
                    foreach (DataColumn item in dataf.Columns)
                    {
                        foreach (var rname in rh)
                        {
                            if (item.ColumnName.ToUpper() == rname.Key.ToUpper())
                            {
                                item.Caption = rname.Caption;
                                colList.Add(item.ColumnName);
                            }
                        }
                    }
                    for (int i = rtItem.DataSource.Columns.Count - 1; i >= 0; i--)
                    {
                        int index = colList.IndexOf(rtItem.DataSource.Columns[i].ColumnName);
                        if (index != -1)
                        {

                        }
                        else
                        {
                            rtItem.DataSource.Columns.Remove(rtItem.DataSource.Columns[i].ColumnName);
                        }
                    }
                }
                //newDt = rtItem.DataSource;
                GetMovNewDt(rtnDIc, baseDataFields, dateFields, comboFields, this.Context);
                FilteNewDt(rtnDIc, parameter);
                // 生成 Excel 字节流
                byte[] excelBytes = DataTableToExcel(rtnDIc);
                // 发送邮件
                foreach (var nmail in parameter.To)
                {
                    SendEmailWithAttachment(excelBytes, nmail, parameter.ScheduleName);
                }
            }
            else
            {
                //获取报表过滤方案的构建基础，便于后续模型构建
                var rptFilterServiceProvider = rptFilterMetadata.BusinessInfo.GetForm().GetFormServiceProvider();
                var rptModel = new SysReportFilterModel();
                rptModel.SetContext(this.Context, rptFilterMetadata.BusinessInfo, rptFilterServiceProvider);
                rptModel.FormId = rptFilterMetadata.BusinessInfo.GetForm().Id;
                rptModel.FilterObject.FilterMetaData = comFilterMetadata;
                rptModel.InitFieldList(rptMetadata, rptFilterMetadata);
                rptModel.GetSchemeList();
                //IsNullOrEmptyOrWhiteSpace()方法须using Kingdee.BOS.Util;
                if (rptFilterSchemeId.IsNullOrEmptyOrWhiteSpace())
                {
                    rptModel.LoadDefaultScheme();//加载默认过滤方案
                }
                else
                {
                    rptModel.Load(rptFilterSchemeId);
                }
                var filterPara = rptModel.GetFilterParameter();
                //报表参数
                IRptParams param = new RptParams();
                param.FormId = rptFilterMetadata.BusinessInfo.GetForm().Id;
                param.StartRow = 1;
                param.EndRow = int.MaxValue;
                param.FilterParameter = filterPara;
                param.FilterFieldInfo = rptModel.FilterFieldInfo;
                param.CustomParams = new Dictionary<string, object>();
                param.CustomParams.Add("OpenParameter", new Dictionary<string, object>());
                //报表服务参数，用于查询。
                var reportServiceParam = new ReportServiceParameter();
                reportServiceParam.RptFilterParams = param;
                reportServiceParam.Context = this.Context;
                reportServiceParam.PageId = Guid.NewGuid().ToString();
                reportServiceParam.BusinessInfo = rptMetadata.BusinessInfo;

                List<BaseDataField> baseDataFields = new List<BaseDataField>();
                List<DateField> dateFields = new List<DateField>();
                List<ComboField> comboFields = new List<ComboField>();
                var typeList = rptMetadata.BusinessInfo.Elements;
                foreach (var type in typeList)
                {
                    var item = type.GetType();
                    var itemName = type.Name;
                    var itemKey = type.Key;
                    var typeName = item.Name;
                    if (typeName.Equals("BaseDataField"))
                    {
                        baseDataFields.Add(type as BaseDataField);
                    }
                    if (typeName.Equals("DateField"))
                    {
                        dateFields.Add(type as DateField);
                    }
                    if (typeName.Equals("ComboField"))
                    {
                        comboFields.Add(type as ComboField);
                    }
                }
                //下一句的resutl.DataSource报表数据的DataTable，物理表名是resutl.DataSource.TableName，可将期数据转储到特定表进行二次加工
                var rh = param.FilterParameter.ColumnInfo;
                var reportData = SysReportServiceHelper.GetReportData(reportServiceParam);
                var dataf = reportData.DataSource;
                List<string> colList = new List<string>();
                DataTable newDt = new DataTable();
                foreach (DataColumn item in dataf.Columns)
                {
                    foreach (var rname in rh)
                    {
                        if (item.ColumnName.ToUpper() == rname.Key.ToUpper())
                        {
                            item.Caption = rname.Caption;
                            colList.Add(item.ColumnName);
                        }
                    }
                }
                for (int i = reportData.DataSource.Columns.Count - 1; i >= 0; i--)
                {
                    int index = colList.IndexOf(reportData.DataSource.Columns[i].ColumnName);
                    if (index != -1)
                    {

                    }
                    else
                    {
                        reportData.DataSource.Columns.Remove(reportData.DataSource.Columns[i].ColumnName);
                    }
                }
                newDt = reportData.DataSource;
                GetNewDt(newDt, baseDataFields, dateFields, comboFields, this.Context);
                newDt = FilteNewDt(newDt, parameter);
                // 生成 Excel 字节流
                byte[] excelBytes = DataTableToExcel(newDt);
                // 发送邮件
                foreach (var nmail in parameter.To)
                {
                    SendEmailWithAttachment(excelBytes, nmail, parameter.ScheduleName);
                }
            }
        }

        private void FilteNewDt(Dictionary<int, IMoveReport> rtnDIc, ScheduleParameter parameter)
        {
            // 筛选条件
            string columnName = parameter.fileName;
            string filterValue = parameter.StartDate.StrDate.ToString();
            string filterValue2 = parameter.StartDate.EndDate.ToString();
            if (columnName.IsNullOrEmptyOrWhiteSpace())
            {
                return;
            }
            foreach (var mov in rtnDIc)
            {
                // 原始 DataTable
                DataTable sourceTable = mov.Value.DataSource;
                // 克隆原始表结构（不含数据）
                DataTable filteredTable = sourceTable;

                // 筛选符合条件的行
                DataRow[] filteredRows = sourceTable.Select($"{columnName} >= '{filterValue}' and {columnName} <= '{filterValue2}' ");

                // 将筛选结果导入新表
                foreach (DataRow row in filteredRows)
                {
                    filteredTable.ImportRow(row);
                }
                //return filteredTable;
            }
        }

        private byte[] DataTableToExcel(Dictionary<int, IMoveReport> movList)
        {
            using (var package = new ExcelPackage())
            {
                foreach (var mov in movList)
                {
                    IMoveReport morRe = mov.Value;
                    DataTable dt = morRe.DataSource;
                    var worksheet = package.Workbook.Worksheets.Add($"Sheet{mov.Key + 1}");

                    // 写入列头
                    for (int i = 0; i < dt.Columns.Count; i++)
                    {
                        worksheet.Cells[1, i + 1].Value = dt.Columns[i].Caption;
                        worksheet.Cells[1, i + 1].Style.Font.Bold = true; // 加粗标题
                        worksheet.Cells[1, i + 1].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
                        worksheet.Cells[1, i + 1].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightGray);
                    }

                    // 写入数据
                    for (int row = 0; row < dt.Rows.Count; row++)
                    {
                        for (int col = 0; col < dt.Columns.Count; col++)
                        {
                            worksheet.Cells[row + 2, col + 1].Value = dt.Rows[row][col];
                        }
                    }

                    // 自动调整列宽
                    worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();
                }
                // 返回 Excel 文件的字节流
                return package.GetAsByteArray();
            }

        }

        private void GetMovNewDt(Dictionary<int, IMoveReport> mov, List<BaseDataField> baseDataFields, List<DateField> dateFields, List<ComboField> comboFields, Context ctx)
        {
            foreach (IMoveReport movdata in mov.Values)
            {
                DataTable newDt = movdata.DataSource;
                foreach (BaseDataField field in baseDataFields)
                {
                    string columnName = field.Key;
                    Type newType = typeof(string);
                    if (newDt.Columns.Contains(columnName))
                    {
                        // 保存原列的位置
                        int originalOrdinal = newDt.Columns[columnName].Ordinal;
                        // 1. 创建临时新列（避免名称冲突）
                        string tempColumnName = $"{columnName}_New";
                        DataColumn newColumn = new DataColumn(tempColumnName, newType);
                        newColumn.Caption = field.Name;
                        newDt.Columns.Add(newColumn);
                        // 2. 迁移数据（处理转换异常）
                        foreach (DataRow row in newDt.Rows)
                        {
                            try
                            {
                                // 尝试将原列值转换为新类型
                                object originalValue = row[columnName];
                                if (originalValue != DBNull.Value && originalValue != null)
                                {
                                    var lookObj = field.LookUpObject;
                                    string formId = lookObj.FormId;
                                    string rValue = row[field.Key].ToString();
                                    // 修改列内容
                                    row[tempColumnName] = GetNewValue(rValue, formId, ctx);
                                    // 使用 Convert.ChangeType 进行安全转换
                                    //row[tempColumnName] = Convert.ChangeType(rValue, newType);
                                }
                                else
                                {
                                    row[tempColumnName] = DBNull.Value;  // 处理空值
                                }
                            }
                            catch (Exception ex)
                            {
                                // 自定义错误处理（例如记录日志或设置默认值）
                                //Console.WriteLine($"转换失败: 行 {row["ID"]}, 值 '{originalValue}'. 错误: {ex.Message}");
                                row[tempColumnName] = DBNull.Value;  // 设为空或默认值
                            }
                        }
                        // 3. 删除旧列
                        newDt.Columns.Remove(columnName);
                        // 4. 重命名新列并调整位置（可选）
                        newColumn.ColumnName = columnName;
                        newColumn.SetOrdinal(originalOrdinal); // 直接使用保存的位置
                    }
                }
                foreach (DateField field in dateFields)
                {
                    string columnName = field.Key;
                    Type newType = typeof(string);
                    if (newDt.Columns.Contains(columnName))
                    {
                        // 保存原列的位置
                        int originalOrdinal = newDt.Columns[columnName].Ordinal;
                        // 1. 创建临时新列（避免名称冲突）
                        string tempColumnName = $"{columnName}_New";
                        DataColumn newColumn = new DataColumn(tempColumnName, newType);
                        newColumn.Caption = field.Name;
                        newDt.Columns.Add(newColumn);
                        // 2. 迁移数据（处理转换异常）
                        foreach (DataRow row in newDt.Rows)
                        {
                            try
                            {
                                // 尝试将原列值转换为新类型
                                DateTime originalValue = (DateTime)row[columnName];
                                row[tempColumnName] = originalValue.ToShortDateString();
                            }
                            catch (Exception ex)
                            {
                                // 自定义错误处理（例如记录日志或设置默认值）
                                //Console.WriteLine($"转换失败: 行 {row["ID"]}, 值 '{originalValue}'. 错误: {ex.Message}");
                                row[tempColumnName] = DBNull.Value;  // 设为空或默认值
                            }
                        }
                        // 3. 删除旧列
                        newDt.Columns.Remove(columnName);
                        // 4. 重命名新列并调整位置（可选）
                        newColumn.ColumnName = columnName;
                        newColumn.SetOrdinal(originalOrdinal); // 直接使用保存的位置
                    }
                }
                foreach (ComboField field in comboFields)
                {
                    string columnName = field.Key;
                    Type newType = typeof(string);
                    if (newDt.Columns.Contains(columnName))
                    {
                        // 保存原列的位置
                        int originalOrdinal = newDt.Columns[columnName].Ordinal;
                        // 1. 创建临时新列（避免名称冲突）
                        string tempColumnName = $"{columnName}_New";
                        DataColumn newColumn = new DataColumn(tempColumnName, newType);
                        newColumn.Caption = field.Name;
                        newDt.Columns.Add(newColumn);
                        // 2. 迁移数据（处理转换异常）
                        foreach (DataRow row in newDt.Rows)
                        {
                            try
                            {
                                // 尝试将原列值转换为新类型
                                object originalValue = row[columnName];
                                if (originalValue != DBNull.Value && originalValue != null)
                                {
                                    var lookObj = field.EnumObject;
                                    string rValue = "";
                                    var iList = lookObj["Items"] as DynamicObjectCollection;
                                    foreach (var item in iList)
                                    {
                                        var str = JsonConvert.SerializeObject(item["Value"]);
                                        string strCaption = item["Caption"].GetString();
                                        if (str == JsonConvert.SerializeObject(originalValue))
                                        {
                                            rValue = strCaption;
                                        }
                                    }

                                    // 修改列内容
                                    row[tempColumnName] = rValue;
                                    // 使用 Convert.ChangeType 进行安全转换
                                    //row[tempColumnName] = Convert.ChangeType(rValue, newType);
                                }
                                else
                                {
                                    row[tempColumnName] = DBNull.Value;  // 处理空值
                                }
                            }
                            catch (Exception ex)
                            {
                                // 自定义错误处理（例如记录日志或设置默认值）
                                //Console.WriteLine($"转换失败: 行 {row["ID"]}, 值 '{originalValue}'. 错误: {ex.Message}");
                                row[tempColumnName] = DBNull.Value;  // 设为空或默认值
                            }
                        }
                        // 3. 删除旧列
                        newDt.Columns.Remove(columnName);
                        // 4. 重命名新列并调整位置（可选）
                        newColumn.ColumnName = columnName;
                        newColumn.SetOrdinal(originalOrdinal); // 直接使用保存的位置
                    }
                }
            }
        }

        private IMoveReport GetReportDataNext(Context ctx, int i, BusinessInfo businessInfo, IRptParams rptParam)
        {
            // 更新分页下标
            rptParam.CurrentPosition = i;
            // 查询数据
            MoveReportServiceParameter param = new MoveReportServiceParameter(ctx, businessInfo, Guid.NewGuid().ToString(), rptParam);
            return SysReportServiceHelper.GetListAndReportData(param);

        }

        private void SendEmailWithAttachment(byte[] excelData, string recipientEmail, string scheduleName)
        {
            try
            {
                //var fromAddress = new MailAddress("mes@bpw.cn", "Data Report");
                var fromAddress = new MailAddress("it@dna-group.com", "Data Report");
                var toAddress = new MailAddress(recipientEmail);

                using (var message = new MailMessage(fromAddress, toAddress))
                {
                    message.Subject = scheduleName;
                    message.Body = "请查收附件中的 Excel 文件。";

                    // 添加附件
                    var stream = new MemoryStream(excelData);
                    var attachment = new Attachment(stream, scheduleName + ".xlsx", MediaTypeNames.Application.Octet);
                    message.Attachments.Add(attachment);

                    // 配置 SMTP
                    using (var smtp = new SmtpClient("smtp.qiye.aliyun.com", 25))
                    {
                        smtp.Credentials = new NetworkCredential("it@dna-group.com", "Dna111222");
                        smtp.EnableSsl = false; // 根据 SMTP 服务器要求启用 SSL
                        smtp.Send(message);
                    }
                }

                Console.WriteLine("邮件发送成功！");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发送失败: {ex.Message}");
            }
        }

        private DataTable FilteNewDt(DataTable newDt, ScheduleParameter parameter)
        {
            // 原始 DataTable
            DataTable sourceTable = newDt;

            // 筛选条件
            string columnName = parameter.fileName;
            string filterValue = parameter.StartDate.StrDate.ToString();
            string filterValue2 = parameter.StartDate.EndDate.ToString();
            if (columnName.IsNullOrEmptyOrWhiteSpace())
            {
                return newDt;
            }

            // 克隆原始表结构（不含数据）
            DataTable filteredTable = sourceTable.Clone();

            // 筛选符合条件的行
            DataRow[] filteredRows = sourceTable.Select($"{columnName} >= '{filterValue}' and {columnName} <= '{filterValue2}' ");

            // 将筛选结果导入新表
            foreach (DataRow row in filteredRows)
            {
                filteredTable.ImportRow(row);
            }
            return filteredTable;
        }

        private void GetNewDt(DataTable newDt, List<BaseDataField> baseDataFields, List<DateField> dateFields, List<ComboField> comboFields, Context ctx)
        {
            foreach (BaseDataField field in baseDataFields)
            {
                string columnName = field.Key;
                Type newType = typeof(string);
                if (newDt.Columns.Contains(columnName))
                {
                    // 保存原列的位置
                    int originalOrdinal = newDt.Columns[columnName].Ordinal;
                    // 1. 创建临时新列（避免名称冲突）
                    string tempColumnName = $"{columnName}_New";
                    DataColumn newColumn = new DataColumn(tempColumnName, newType);
                    newColumn.Caption = field.Name;
                    newDt.Columns.Add(newColumn);
                    // 2. 迁移数据（处理转换异常）
                    foreach (DataRow row in newDt.Rows)
                    {
                        try
                        {
                            // 尝试将原列值转换为新类型
                            object originalValue = row[columnName];
                            if (originalValue != DBNull.Value && originalValue != null)
                            {
                                var lookObj = field.LookUpObject;
                                string formId = lookObj.FormId;
                                string rValue = row[field.Key].ToString();
                                // 修改列内容
                                row[tempColumnName] = GetNewValue(rValue, formId, ctx);
                                // 使用 Convert.ChangeType 进行安全转换
                                //row[tempColumnName] = Convert.ChangeType(rValue, newType);
                            }
                            else
                            {
                                row[tempColumnName] = DBNull.Value;  // 处理空值
                            }
                        }
                        catch (Exception ex)
                        {
                            // 自定义错误处理（例如记录日志或设置默认值）
                            //Console.WriteLine($"转换失败: 行 {row["ID"]}, 值 '{originalValue}'. 错误: {ex.Message}");
                            row[tempColumnName] = DBNull.Value;  // 设为空或默认值
                        }
                    }
                    // 3. 删除旧列
                    newDt.Columns.Remove(columnName);
                    // 4. 重命名新列并调整位置（可选）
                    newColumn.ColumnName = columnName;
                    newColumn.SetOrdinal(originalOrdinal); // 直接使用保存的位置
                }
            }
            foreach (DateField field in dateFields)
            {
                string columnName = field.Key;
                Type newType = typeof(string);
                if (newDt.Columns.Contains(columnName))
                {
                    // 保存原列的位置
                    int originalOrdinal = newDt.Columns[columnName].Ordinal;
                    // 1. 创建临时新列（避免名称冲突）
                    string tempColumnName = $"{columnName}_New";
                    DataColumn newColumn = new DataColumn(tempColumnName, newType);
                    newColumn.Caption = field.Name;
                    newDt.Columns.Add(newColumn);
                    // 2. 迁移数据（处理转换异常）
                    foreach (DataRow row in newDt.Rows)
                    {
                        try
                        {
                            // 尝试将原列值转换为新类型
                            DateTime originalValue = (DateTime)row[columnName];
                            row[tempColumnName] = originalValue.ToShortDateString();
                        }
                        catch (Exception ex)
                        {
                            // 自定义错误处理（例如记录日志或设置默认值）
                            //Console.WriteLine($"转换失败: 行 {row["ID"]}, 值 '{originalValue}'. 错误: {ex.Message}");
                            row[tempColumnName] = DBNull.Value;  // 设为空或默认值
                        }
                    }
                    // 3. 删除旧列
                    newDt.Columns.Remove(columnName);
                    // 4. 重命名新列并调整位置（可选）
                    newColumn.ColumnName = columnName;
                    newColumn.SetOrdinal(originalOrdinal); // 直接使用保存的位置
                }
            }
            foreach (ComboField field in comboFields)
            {
                string columnName = field.Key;
                Type newType = typeof(string);
                if (newDt.Columns.Contains(columnName))
                {
                    // 保存原列的位置
                    int originalOrdinal = newDt.Columns[columnName].Ordinal;
                    // 1. 创建临时新列（避免名称冲突）
                    string tempColumnName = $"{columnName}_New";
                    DataColumn newColumn = new DataColumn(tempColumnName, newType);
                    newColumn.Caption = field.Name;
                    newDt.Columns.Add(newColumn);
                    // 2. 迁移数据（处理转换异常）
                    foreach (DataRow row in newDt.Rows)
                    {
                        try
                        {
                            // 尝试将原列值转换为新类型
                            object originalValue = row[columnName];
                            if (originalValue != DBNull.Value && originalValue != null)
                            {
                                var lookObj = field.EnumObject;
                                string rValue = "";
                                var iList = lookObj["Items"] as DynamicObjectCollection;
                                foreach (var item in iList)
                                {
                                    var str = JsonConvert.SerializeObject(item["Value"]);
                                    string strCaption = item["Caption"].GetString();
                                    if (str == JsonConvert.SerializeObject(originalValue))
                                    {
                                        rValue = strCaption;
                                    }
                                }

                                // 修改列内容
                                row[tempColumnName] = rValue;
                                // 使用 Convert.ChangeType 进行安全转换
                                //row[tempColumnName] = Convert.ChangeType(rValue, newType);
                            }
                            else
                            {
                                row[tempColumnName] = DBNull.Value;  // 处理空值
                            }
                        }
                        catch (Exception ex)
                        {
                            // 自定义错误处理（例如记录日志或设置默认值）
                            //Console.WriteLine($"转换失败: 行 {row["ID"]}, 值 '{originalValue}'. 错误: {ex.Message}");
                            row[tempColumnName] = DBNull.Value;  // 设为空或默认值
                        }
                    }
                    // 3. 删除旧列
                    newDt.Columns.Remove(columnName);
                    // 4. 重命名新列并调整位置（可选）
                    newColumn.ColumnName = columnName;
                    newColumn.SetOrdinal(originalOrdinal); // 直接使用保存的位置
                }
            }
        }

        private object GetNewValue(string rValue, string formId, Context ctx)
        {
            var obj = GetDynamicObjectByFormIdAndId(ctx, formId, rValue);
            string name = obj["name"].ToString();
            return name;
        }

        private DynamicObject GetDynamicObjectByFormIdAndId(Context context, string formId, string fid)
        {
            DynamicObject obj = null;
            FormMetadata meta = MetaDataServiceHelper.GetFormMetaData(context, formId);
            QueryBuilderParemeter queryParam = new QueryBuilderParemeter();
            queryParam.FormId = formId;
            queryParam.FilterClauseWihtKey = string.Format(" {0}='{1}'", meta.BusinessInfo.GetForm().PkFieldName, fid);
            var objs = BusinessDataServiceHelper.Load(context, meta.BusinessInfo.GetDynamicObjectType(), queryParam);
            if (objs.Length > 0) obj = objs.FirstOrDefault();
            return obj;
        }

        private DataTable GetSqlRptData(Context context, FormMetadata rptMetadata, string f_DateStr, StartDate strAndEndDate, string rptFilterSchemeId)
        {
            DataTable dt = null;
            ISQLReportService service = ServiceFactory.GetSQLReportService(this.Context);
            SQLFilterParameter filter = new SQLFilterParameter();
            SysReportForm form = rptMetadata.BusinessInfo.GetForm() as SysReportForm;
            try
            {
                List<FilterSettingItem> sqlKeyValue = new List<FilterSettingItem>();
                string xmlContent = GetxmlString(rptFilterSchemeId);
                // 第一步：XML 反序列化
                var xmlSerializer = new XmlSerializer(typeof(SQLFilterSchemeEntity));
                SQLFilterSchemeEntity entity;
                using (var reader = new StringReader(xmlContent))
                {
                    entity = (SQLFilterSchemeEntity)xmlSerializer.Deserialize(reader);
                }

                // 第二步：JSON 反序列化（关键修正点）
                sqlKeyValue = JsonConvert.DeserializeObject<List<FilterSettingItem>>(entity.SQLFilterSettingJson);
                foreach (var keyword in form.SQLDataSource.KeyWordList)
                {
                    SQLFilterField filterField = new SQLFilterField();
                    filterField.Caption = keyword.Name;
                    filterField.IsAllowInput = keyword.IsAllowInput;
                    filterField.IsMultiSelect = keyword.IsMultiSelect;
                    filterField.KeyWord = keyword.KeyWord;
                    foreach (var sqlr in sqlKeyValue)
                    {
                        if (sqlr.KeyWord == keyword.KeyWord)
                        {
                            SQLFilterRow filterRow = new SQLFilterRow(filterField, sqlr.Value, filterField.Caption, false);
                            filter.SQLFilterRows.Add(filterRow);
                        }
                    }
                }
                SqlReportQueryResult sqlReportQueryResult = service.CreateDirectSqlData(this.Context, filter, form.SQLDataSource);

                if (sqlReportQueryResult.DataSource == null)
                {
                    if (sqlReportQueryResult.TableName.IsNullOrEmptyOrWhiteSpace() == false)
                    {
                        dt = DBUtils.ExecuteDataSet(this.Context, string.Format("SELECT * FROM {0}", sqlReportQueryResult.TableName)).Tables[0];
                    }
                }
                else
                {
                    dt = sqlReportQueryResult.DataSource;
                }
            }
            catch (Exception ex) { }
            if (dt.Columns.Contains("FIDENTITYID"))
            {
                dt.Columns.Remove("FIDENTITYID");
            }
            // 原始 DataTable
            DataTable sourceTable = dt;

            // 筛选条件
            string columnName = f_DateStr;
            string filterValue = strAndEndDate.StrDate.ToString();
            string filterValue2 = strAndEndDate.EndDate.ToString();

            // 克隆原始表结构（不含数据）
            DataTable filteredTable = sourceTable.Clone();

            // 筛选符合条件的行
            DataRow[] filteredRows = sourceTable.Select($"{columnName} >= '{filterValue}' and {columnName} <= '{filterValue2}' ");

            // 将筛选结果导入新表
            foreach (DataRow row in filteredRows)
            {
                filteredTable.ImportRow(row);
            }

            return filteredTable;
        }

        private string GetxmlString(string rptFilterSchemeId)
        {
            string sql = string.Format(@"/*dialect*/ 
            select FSCHEME from T_BAS_FILTERSCHEME where FSCHEMEID='{0}'  ", rptFilterSchemeId);
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(this.Context, sql);
            if (doc.Count > 0)
            {
                return doc[0][0].ToString();
            }
            return "";
        }

        private void SendEmailWithAttachment(byte[] excelData, string recipientEmail)
        {
            try
            {
                var fromAddress = new MailAddress("it@dna-group.com", "Data Report");
                var toAddress = new MailAddress(recipientEmail);

                using (var message = new MailMessage(fromAddress, toAddress))
                {
                    message.Subject = "Data Report Attachment";
                    message.Body = "请查收附件中的 Excel 文件。";

                    // 添加附件
                    var stream = new MemoryStream(excelData);
                    var attachment = new Attachment(stream, "Report.xlsx", MediaTypeNames.Application.Octet);
                    message.Attachments.Add(attachment);

                    // 配置 SMTP
                    using (var smtp = new SmtpClient("smtp.qiye.aliyun.com", 25))
                    {
                        smtp.Credentials = new NetworkCredential("it@dna-group.com", "Dna111222");
                        smtp.EnableSsl = false; // 根据 SMTP 服务器要求启用 SSL
                        smtp.Send(message);
                    }
                }

                Console.WriteLine("邮件发送成功！");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发送失败: {ex.Message}");
            }
        }

        private byte[] DataTableToExcel(DataTable dt)
        {
            using (var package = new ExcelPackage())
            {
                var worksheet = package.Workbook.Worksheets.Add("Sheet1");

                // 写入列头
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    worksheet.Cells[1, i + 1].Value = dt.Columns[i].Caption;
                    worksheet.Cells[1, i + 1].Style.Font.Bold = true; // 加粗标题
                    worksheet.Cells[1, i + 1].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
                    worksheet.Cells[1, i + 1].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightGray);
                }

                // 写入数据
                for (int row = 0; row < dt.Rows.Count; row++)
                {
                    for (int col = 0; col < dt.Columns.Count; col++)
                    {
                        worksheet.Cells[row + 2, col + 1].Value = dt.Rows[row][col];
                    }
                }

                // 自动调整列宽
                worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();

                // 返回 Excel 文件的字节流
                return package.GetAsByteArray();
            }
        }

        private bool AddSchedule(string scheduleName, DynamicObject obj, IBillView view, StartDate strAndEndDate, string fileName)
        {
            List<DynamicObject> saveObjects = new List<DynamicObject>();
            ((IBillViewService)view).LoadData();
            DynamicFormViewPlugInProxy eventProxy = view.GetService<DynamicFormViewPlugInProxy>();
            eventProxy.FireOnLoad();
            //服务插件
            view.Model.SetValue("FSCHEDULECLASS", BaseParam.scheduleClassName);
            //名称
            view.Model.SetValue("FNAME", scheduleName);
            //描述
            view.Model.SetValue("FDESCRIPTION", "自动生成" + DateTime.Now);
            //执行间隔时间
            view.Model.SetValue("FEXECUTEINTERVAL", Convert.ToInt32(obj["FEXECUTEINTERVAL"]));
            //执行间隔单位
            view.Model.SetValue("FEXECUTEINTERVALUNIT", obj["FEXECUTEINTERVALUNIT"]);
            //执行时间
            var a = obj["FEXECUTETIME"];
            view.Model.SetValue("FEXECUTETIME", obj["FEXECUTETIME"]);
            //开始时间
            view.Model.SetValue("FBEGINTIME", obj["FBEGINTIME"]);
            //异步执行
            view.Model.SetValue("FISASYNCJOB", false);
            //任务状态
            view.Model.SetValue("FSTATUS", "0");
            //结束时间
            view.Model.SetValue("FENDTIME", obj["FENDTIME"]);
            //参数表单Id
            view.Model.SetValue("FPARAMETERFORMID", "");
            //参数
            string parm = GetParameters(obj, scheduleName, strAndEndDate, fileName);
            view.Model.SetValue("FParameters", parm);
            //异常后自动恢复
            view.Model.SetValue("FISAutoExecute", true);
            //异常恢复间隔时间(分钟)
            view.Model.SetValue("FAUTORECOVERYTIME", 120);
            saveObjects.Add(view.Model.DataObject);
            //删除消息接收人明细行
            view.Model.DeleteEntryData("FMsgConfigEntry");
            if (saveObjects.Count > 0)
            {
                var result = BusinessDataServiceHelper.Save(view.Context, view.BusinessInfo, saveObjects.ToArray());
                if (result.IsSuccess)
                {
                    this.View.ShowMessage($"名称为：{scheduleName}的执行计划创建成功", MessageBoxType.Notice);
                    return true;
                }
                else
                {
                    this.View.ShowErrMessage($"名称为：{scheduleName}的执行计划创建失败_02", "创建失败", MessageBoxType.Error);
                    return false;
                }
            }
            else
            {
                this.View.ShowErrMessage($"名称为：{scheduleName}的执行计划创建失败_03", "创建失败", MessageBoxType.Error);
                return false;
            }
        }

        private string GetParameters(DynamicObject obj, string scheduleName, StartDate strAndEndDate, string fileName)
        {
            List<string> list = new List<string>();
            var users = obj["F_POSW_MulBaseUsers"] as DynamicObjectCollection;
            foreach (var user in users)
            {
                int uid = Convert.ToInt32(user["F_POSW_MulBaseUsers_id"]);
                string mail = GetMail(uid);
                if (!mail.IsNullOrEmptyOrWhiteSpace())
                {
                    list.Add(mail);
                }
            }
            var form = obj["F_POSW_YWDX"] as DynamicObject;
            ScheduleParameter parameter = new ScheduleParameter();
            parameter.UserName = this.Context.UserName;
            parameter.RptFormId = form == null ? "" : form["id"].ToString();
            parameter.RptFilterFormId = obj["FRptFilterFormId"].ToString();
            parameter.SchemeId = obj["F_POSW_Filter"].ToString();
            parameter.To = list;
            parameter.ScheduleName = scheduleName;
            parameter.fileName = fileName;
            parameter.StartDate = strAndEndDate;
            return JsonConvert.SerializeObject(parameter);
        }
        private ScheduleParameter GetParametersObj(DynamicObject obj, string scheduleName, StartDate strAndEndDate, string fileName)
        {
            List<string> list = new List<string>();
            var users = obj["F_POSW_MulBaseUsers"] as DynamicObjectCollection;
            foreach (var user in users)
            {
                int uid = Convert.ToInt32(user["F_POSW_MulBaseUsers_id"]);
                string mail = GetMail(uid);
                if (!mail.IsNullOrEmptyOrWhiteSpace())
                {
                    list.Add(mail);
                }
            }
            var form = obj["F_POSW_YWDX"] as DynamicObject;
            ScheduleParameter parameter = new ScheduleParameter();
            parameter.UserName = this.Context.UserName;
            parameter.RptFormId = form == null ? "" : form["id"].ToString();
            parameter.RptFilterFormId = obj["FRptFilterFormId"].ToString();
            parameter.SchemeId = obj["F_POSW_Filter"].ToString();
            parameter.To = list;
            parameter.ScheduleName = scheduleName;
            parameter.fileName = fileName;
            parameter.StartDate = strAndEndDate;
            return parameter;
        }

        private string GetMail(int uid)
        {
            //SELECT FEMAIL FROM T_SEC_USER WHERE FUSERID=100473
            string sql = string.Format(@"/*dialect*/ 
            SELECT FEMAIL FROM T_SEC_USER WHERE FUSERID={0} ", uid);
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(this.Context, sql);
            if (doc.Count > 0)
            {
                return doc[0][0].ToString();
            }
            return "";
        }

        private bool CheckSchedule(string scheduleName, IBillView view)
        {
            //检查是否已经存在同名定时任务
            string where = string.Format(" FName='{0}' ", scheduleName);
            DynamicObject[] objs = GetDynamicObjectByFormIdAndId(view, where);
            if (objs.Count() > 0)
            {
                return false;
            }
            return true;
        }

        private string GetScheduleName(DynamicObject obj)
        {
            var form = obj["F_POSW_YWDX"] as DynamicObject;
            string formName = form == null ? "" : form["name"].GetString();
            var filter = obj["F_POSW_Filter"].ToString();

            var ts = obj["id"].ToString();
            return formName + "_" + filter + "_" + ts;
        }

        private bool AddSendMailTask()
        {
            throw new NotImplementedException();
        }

        private bool AddListExportTask(string scheduleName, DynamicObject obj)
        {
            IBillView view = CreateBillView(this.Context, "BOS_SCHEDULETYPE");
            //检查是否已经存在同名定时任务
            bool isHave = CheckExport(view, scheduleName);
            if (isHave)
            {
                bool isExcel = CreateExcelTask(obj);
                bool isCreate = CreateExportTask(view, scheduleName);
            }
            return true;
        }
        /// <summary>
        /// 生成后台引出EXCEL文件执行
        /// </summary>
        /// <returns></returns>
        private bool CreateExcelTask(DynamicObject obj)
        {
            AddTask(obj);
            return true;
        }

        private void AddTask(DynamicObject obj)
        {
            //actionType = (BackgroudPrintActionType)10;
            //DynamicObject val = obj["F_POSW_YWDX"] as DynamicObject;
            //formId = val["Id"].ToString();
            //formName = ((object)(LocaleValue)val["Name"]).ToString();
            //schemeId = ((AbstractDynamicFormPlugIn)this).Model.GetValue("FSchemeId").ToString();
            //EnumItem val2 = filterSchemeEnumList.FirstOrDefault((EnumItem o) => o.Value == schemeId);
            //if (val2 != null)
            //{
            //    //schemeName = LocaleValue.op_Implicit(val2.Caption);
            //    schemeName = new LocaleValue(val2.Caption);
            //}
            //formMetaData = FormMetaDataCache.GetCachedFormMetaData(((AbstractDynamicFormPlugIn)this).View.Context, formId);
            //formBusinessInfo = formMetaData.BusinessInfo;
            //notePrintOperationType = (NotePrintOperationType)(-1);
            //if ((int)actionType == 0)
            //{
            //    if (!IsNotePrint)
            //    {
            //        ((AbstractDynamicFormPlugIn)this).View.ShowErrMessage(ResManager.LoadKDString("当前打印类型暂不支持", "002014000004890", (SubSystemType)2, new object[0]), "", (MessageBoxType)0);
            //        return;
            //    }
            //    if (((AbstractBusinessMetadata)formMetaData).ModelTypeId == 100 || ((AbstractBusinessMetadata)formMetaData).ModelTypeId == 400)
            //    {
            //        AddListReportToTaskQueue();
            //        return;
            //    }
            //    if (((AbstractBusinessMetadata)formMetaData).ModelTypeSubId == 902)
            //    {
            //        AddMoveReportToTaskQueue();
            //        return;
            //    }
            //    if (((AbstractBusinessMetadata)formMetaData).ModelTypeSubId == 900)
            //    {
            //        AddSysReportToTaskQueue();
            //        return;
            //    }
            //    if (((AbstractBusinessMetadata)formMetaData).ModelTypeSubId == 903)
            //    {
            //        AddSysReportToTaskQueue();
            //        return;
            //    }
            //}
            //if ((int)actionType == 5)
            //{
            //    if (!IsNotePrint)
            //    {
            //        ((AbstractDynamicFormPlugIn)this).View.ShowErrMessage(ResManager.LoadKDString("当前打印类型暂不支持", "002014000004890", (SubSystemType)2, new object[0]), "", (MessageBoxType)0);
            //        return;
            //    }
            //    if (((AbstractBusinessMetadata)formMetaData).ModelTypeId == 100 || ((AbstractBusinessMetadata)formMetaData).ModelTypeId == 400)
            //    {
            //        AddListReportNoteExportToTaskQueue();
            //        return;
            //    }
            //    if (((AbstractBusinessMetadata)formMetaData).ModelTypeSubId == 902)
            //    {
            //        AddSysReportNoteExportToTaskQueue();
            //        return;
            //    }
            //    if (((AbstractBusinessMetadata)formMetaData).ModelTypeSubId == 900)
            //    {
            //        AddSysReportNoteExportToTaskQueue();
            //        return;
            //    }
            //    if (((AbstractBusinessMetadata)formMetaData).ModelTypeSubId == 903)
            //    {
            //        AddSysReportNoteExportToTaskQueue();
            //        return;
            //    }
            //}
            //if ((int)actionType == 10)
            //{
            //    if (((AbstractBusinessMetadata)formMetaData).ModelTypeId == 100 || ((AbstractBusinessMetadata)formMetaData).ModelTypeId == 400)
            //    {
            //        AddListExportTask(Guid.NewGuid().ToString());
            //        return;
            //    }
            //    if (((AbstractBusinessMetadata)formMetaData).ModelTypeSubId == 902)
            //    {
            //        AddListExportTask(Guid.NewGuid().ToString());
            //        return;
            //    }
            //    if (((AbstractBusinessMetadata)formMetaData).ModelTypeSubId == 900)
            //    {
            //        AddListExportTask(Guid.NewGuid().ToString());
            //        return;
            //    }
            //    if (((AbstractBusinessMetadata)formMetaData).ModelTypeSubId == 903)
            //    {
            //        AddListExportTask(Guid.NewGuid().ToString());
            //        return;
            //    }
            //}
        }

        /// <summary>
        /// 创建发送邮件执行计划
        /// </summary>
        /// <param name="view"></param>
        /// <param name="scheduleName"></param>
        /// <returns></returns>
        private bool CreateExportTask(IBillView view, string scheduleName)
        {
            List<DynamicObject> saveObjects = new List<DynamicObject>();
            DateTime dateTime = BaseParam.GetServerTime(this.Context);
            ((IBillViewService)view).LoadData();
            DynamicFormViewPlugInProxy eventProxy = view.GetService<DynamicFormViewPlugInProxy>();
            eventProxy.FireOnLoad();
            //服务插件
            view.Model.SetValue("FSCHEDULECLASS", BaseParam.scheduleClassName);
            //名称
            view.Model.SetValue("FNAME", scheduleName);
            //描述
            view.Model.SetValue("FDESCRIPTION", "自动生成" + dateTime.ToLongDateString());
            //执行间隔时间
            view.Model.SetValue("FEXECUTEINTERVAL", 60);
            //执行间隔单位
            view.Model.SetValue("FEXECUTEINTERVALUNIT", 1);
            //执行时间
            view.Model.SetValue("FEXECUTETIME", dateTime.ToShortDateString());
            //开始时间
            view.Model.SetValue("FBEGINTIME", dateTime.AddDays(-1).ToShortDateString());
            //异步执行
            view.Model.SetValue("FISASYNCJOB", false);
            //任务状态
            view.Model.SetValue("FSTATUS", "0");
            //结束时间
            view.Model.SetValue("FENDTIME", DateTime.MaxValue.ToShortDateString());
            //参数表单Id
            view.Model.SetValue("FPARAMETERFORMID", "");
            //参数
            JSONObject json = new JSONObject();
            //json.Add("FOrgId", useOrg["id"]);
            //json.Add("FFormId", form["id"]);
            //json.Add("FOperationNumber", operationNumber);
            //json.Add("FOpId", kAndOSysSynOpStView.Model.DataObject["id"]);
            view.Model.SetValue("FParameters", json.ToJSONString());
            //异常后自动恢复
            view.Model.SetValue("FISAutoExecute", true);
            //异常恢复间隔时间(分钟)
            view.Model.SetValue("FAUTORECOVERYTIME", 120);
            saveObjects.Add(view.Model.DataObject);
            //删除消息接收人明细行
            view.Model.DeleteEntryData("FMsgConfigEntry");
            if (saveObjects.Count > 0)
            {
                var result = BusinessDataServiceHelper.Save(view.Context, view.BusinessInfo, saveObjects.ToArray());
                if (result.IsSuccess)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        private bool CheckExport(IBillView view, string scheduleName)
        {
            //检查是否已经存在同名定时任务
            string where = string.Format(" FName='{0}' ", scheduleName);
            DynamicObject[] objs = GetDynamicObjectByFormIdAndId(view, where);
            if (objs.Count() > 0)
            {
                return false;
            }
            return true;
        }

        private DynamicObject[] GetDynamicObjectByFormIdAndId(IBillView view, string where)
        {
            DynamicObject obj = null;
            QueryBuilderParemeter queryParam = new QueryBuilderParemeter();
            queryParam.FormId = view.BusinessInfo.GetForm().Id;
            queryParam.FilterClauseWihtKey = where;
            queryParam.TopRowCount = 1000;
            var objs = BusinessDataServiceHelper.Load(view.Context, view.BusinessInfo.GetDynamicObjectType(), queryParam);
            return objs;
        }

        private IBillView CreateBillView(Context context, string formId)
        {
            // 读取物料的元数据
            FormMetadata meta = MetaDataServiceHelper.Load(context, formId) as FormMetadata;
            Form form = meta.BusinessInfo.GetForm();

            // 创建用于引入数据的单据view
            Type type = Type.GetType("Kingdee.BOS.Web.Import.ImportBillView,Kingdee.BOS.Web");
            var billView = (IDynamicFormViewService)Activator.CreateInstance(type);
            // 开始初始化billView：
            // 创建视图加载参数对象，指定各种参数，如FormId, 视图(LayoutId)等
            BillOpenParameter openParam = CreateOpenParameter(context, meta);
            // 动态领域模型服务提供类，通过此类，构建MVC实例
            var provider = form.GetFormServiceProvider();
            billView.Initialize(openParam, provider);
            return billView as IBillView;
        }

        private BillOpenParameter CreateOpenParameter(Context context, FormMetadata meta)
        {
            Form form = meta.BusinessInfo.GetForm();
            // 指定FormId, LayoutId
            BillOpenParameter openParam = new BillOpenParameter(form.Id, meta.GetLayoutInfo().Id);
            // 数据库上下文
            openParam.Context = context;
            // 本单据模型使用的MVC框架
            openParam.ServiceName = form.FormServiceName;
            // 随机产生一个不重复的PageId，作为视图的标识
            openParam.PageId = Guid.NewGuid().ToString();
            // 元数据
            openParam.FormMetaData = meta;
            // 界面状态：新增 (修改、查看)
            openParam.Status = OperationStatus.ADDNEW;
            // 单据主键：本案例演示新建物料，不需要设置主键
            openParam.PkValue = null;
            // 界面创建目的：普通无特殊目的 （为工作流、为下推、为复制等）
            openParam.CreateFrom = CreateFrom.Default;
            // 基础资料分组维度：基础资料允许添加多个分组字段，每个分组字段会有一个分组维度
            // 具体分组维度Id，请参阅 form.FormGroups 属性
            openParam.GroupId = "";
            // 基础资料分组：如果需要为新建的基础资料指定所在分组，请设置此属性
            openParam.ParentId = 0;
            // 单据类型
            openParam.DefaultBillTypeId = "";
            // 业务流程
            openParam.DefaultBusinessFlowId = "";
            // 主业务组织改变时，不用弹出提示界面
            openParam.SetCustomParameter("ShowConfirmDialogWhenChangeOrg", false);
            // 插件
            List<AbstractDynamicFormPlugIn> plugs = form.CreateFormPlugIns();
            openParam.SetCustomParameter(FormConst.PlugIns, plugs);
            //PreOpenFormEventArgs args = new PreOpenFormEventArgs(context, openParam);
            //foreach (var plug in plugs)
            //{// 触发插件PreOpenForm事件，供插件确认是否允许打开界面
            //    plug.PreOpenForm(args);
            //}
            //if (args.Cancel == true)
            //{// 插件不允许打开界面
            //    // 本案例不理会插件的诉求，继续....
            //}
            // 返回
            return openParam;
        }

        //public override void DataChanged(DataChangedEventArgs e)
        //{
        //    base.DataChanged(e);
        //    var obj = this.Model.DataObject;
        //    if (e.Field.Key.EqualsIgnoreCase("F_POSW_YWDX") && this.Model.OpenParameter.Status == OperationStatus.ADDNEW)
        //    {
        //        string formId = e.NewValue.GetString();
        //        DynamicObjectCollection schemes = GetSchemes(this.Context, formId);
        //        if (schemes.Count == 0) { return; }
        //        List<EnumItem> items = new List<EnumItem>();
        //        foreach (var item in schemes)
        //        {
        //            EnumItem enumItem = new EnumItem();
        //            enumItem.Value = item["FSEQ"].ToString();
        //            enumItem.Caption = new LocaleValue(item["FSCHEMENAME"].ToString());
        //            items.Add(enumItem);
        //        }
        //        this.View.GetFieldEditor<ComboFieldEditor>("F_POSW_Filter2", 0).SetComboItems(items);
        //    }
        //}

        private DynamicObjectCollection GetSchemes(Context context, string formId)
        {
            string sql = string.Format(@"/*dialect*/ 
            select ROW_NUMBER() OVER (ORDER BY FUSERID) FSEQ,FSCHEMENAME from T_BAS_FILTERSCHEME where FFORMID='{0}'  AND FUSERID>0 ", formId);
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(context, sql);
            return doc;
        }

        //public override void AfterBindData(EventArgs e)
        //{
        //    base.AfterBindData(e);
        //    List<EnumItem> items = new List<EnumItem>();
        //    EnumItem enumItem = new EnumItem();
        //    //enumItem.EnumId = "1";
        //    enumItem.Caption = new LocaleValue("测试方案");
        //    enumItem.Value = "0";
        //    items.Add(enumItem);
        //    this.View.GetFieldEditor<ComboFieldEditor>("F_POSW_Filter2", 0).SetComboItems(items);
        //}
        //public override void FireBeforeExportTitle(BeforeExportTitleArg e)
        //{
        //    base.FireBeforeExportTitle(e);
        //}
        //public override void BeforeBindData(EventArgs e)
        //{
        //    base.BeforeBindData(e);

        //}
        public override void BeforeF7Select(BeforeF7SelectEventArgs e)
        {
            base.BeforeF7Select(e);
            //过滤方案
            if (e.FieldKey.Equals("F_POSW_Filter"))
            {
                var form = this.Model.DataObject["F_POSW_YWDX"] as DynamicObject;
                if (form.IsNullOrEmptyOrWhiteSpace())
                {
                    this.View.ShowErrMessage("请先选择业务单据！");
                    return;
                }
                string formId = form["id"].ToString();
                ShowAndFillFilter(e.Row, formId);
            }
            //报表日期标识
            if (e.FieldKey.Equals("F_DateStr"))
            {
                var form = this.Model.DataObject["F_POSW_YWDX"] as DynamicObject;
                if (form.IsNullOrEmptyOrWhiteSpace())
                {
                    this.View.ShowErrMessage("请先选择业务单据！");
                    return;
                }
                var FRptFilterFormId = this.Model.DataObject["FRptFilterFormId"].ToString();
                var F_POSW_Filter = this.Model.DataObject["F_POSW_Filter"].ToString();
                if (FRptFilterFormId.IsNullOrEmptyOrWhiteSpace() || F_POSW_Filter.IsNullOrEmptyOrWhiteSpace())
                {
                    this.View.ShowErrMessage("过滤方案和账表的过滤窗体不能为空！");
                    return;
                }
                string formId = form["id"].ToString();
                ShowDateList(e.Row, formId, this.Context, FRptFilterFormId, F_POSW_Filter);
            }
        }

        private void ShowDateList(int row, string rptFormId, Context ctx, string rptFilterFormId, string rptFilterSchemeId)
        {
            //获取相关元数据  POSW_ReportDateList
            var comFilterMetadata = FormMetaDataCache.GetCachedFilterMetaData(ctx);
            var rptMetadata = FormMetaDataCache.GetCachedFormMetaData(ctx, rptFormId);
            var rptFilterMetadata = FormMetaDataCache.GetCachedFormMetaData(ctx, rptFilterFormId);
            var rptType = rptMetadata.BaseObjectId;
            if (rptType == "BOS_SQLReport")
            {
                DataTable sqlDt = GetSqlRptData(ctx, rptMetadata, rptFilterSchemeId);
                List<DataColumn> filterList = new List<DataColumn>();
                foreach (DataColumn col in sqlDt.Columns)
                {
                    filterList.Add(col);
                }
                DynamicFormShowParameter formpa = new DynamicFormShowParameter();
                formpa.FormId = "POSW_ReportDateList";
                formpa.CustomParams.Add("dateList", JsonConvert.SerializeObject(filterList));
                this.View.ShowForm(formpa, delegate (FormResult result)
                {
                    var rdata = result.ReturnData as DynamicObject;
                    if (rdata != null)
                    {
                        var v = rdata[0];
                        var name = rdata[1];
                        this.View.Model.SetValue("F_DateStr", v);
                        this.View.Model.SetValue("F_DateName", name);
                    }
                });
            }
            else if (rptType == "BOS_MoveSysReport")
            {
                var reportFilterServiceProvider = rptFilterMetadata.BusinessInfo.GetForm().GetFormServiceProvider();
                var model = new SysReportFilterModel();
                model.SetContext(ctx, rptFilterMetadata.BusinessInfo, reportFilterServiceProvider);
                model.FormId = rptFilterMetadata.BusinessInfo.GetForm().Id;
                model.FilterObject.FilterMetaData = comFilterMetadata;
                model.InitFieldList(rptMetadata, rptFilterMetadata);
                model.GetSchemeList();//过滤方案的主键值，可通过该SQL语句查询得到：SELECT * FROM T_BAS_FILTERSCHEME
                var entity = model.Load(rptFilterSchemeId);
                var dyn = DeserializeCustomFilter(rptFilterMetadata.BusinessInfo, entity.CustomFilterSetting);
                model.DataObject = dyn;
                var filter = model.GetFilterParameter();
                IRptParams rptParam = new RptParams();
                rptParam.FormId = rptFilterMetadata.BusinessInfo.GetForm().Id;
                rptParam.CurrentPosition = 1;//分页账表当前位置
                rptParam.StartRow = 1;
                rptParam.EndRow = int.MaxValue;//StartRow和EndRow是报表数据分页的起始行数和截至行数，一般取所有数据，所以EndRow取int最大值。
                rptParam.FilterParameter = filter;
                rptParam.FilterFieldInfo = model.FilterFieldInfo;
                var dic = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
                foreach (var itemProp in dyn.DynamicObjectType.Properties)
                {
                    dic[itemProp.Name] = dyn[itemProp.Name];
                }
                rptParam.CustomParams.Add("OpenParameter", dic);
                MoveReportServiceParameter param = new MoveReportServiceParameter(ctx, rptMetadata.BusinessInfo, Guid.NewGuid().ToString(), rptParam);
                var movReport = SysReportServiceHelper.GetListAndReportData(param);
                List<BaseDataField> baseDataFields = new List<BaseDataField>();
                List<DateField> dateFields = new List<DateField>();
                List<ComboField> comboFields = new List<ComboField>();
                var typeList = rptMetadata.BusinessInfo.Elements;
                foreach (var type in typeList)
                {
                    var item = type.GetType();
                    var itemName = type.Name;
                    var itemKey = type.Key;
                    var typeName = item.Name;
                    if (typeName.Equals("BaseDataField"))
                    {
                        baseDataFields.Add(type as BaseDataField);
                    }
                    if (typeName.Equals("DateField"))
                    {
                        dateFields.Add(type as DateField);
                    }
                    if (typeName.Equals("ComboField"))
                    {
                        comboFields.Add(type as ComboField);
                    }
                }
                var dataf = movReport.DataSource;
                List<DataColumn> filterList = new List<DataColumn>();
                foreach (DateField item in dateFields)
                {
                    DataColumn col = new DataColumn();
                    col.ColumnName = item.Key;
                    col.Caption = item.Name;
                    filterList.Add(col);
                }
                DynamicFormShowParameter formpa = new DynamicFormShowParameter();
                formpa.FormId = "POSW_ReportDateList";
                formpa.CustomParams.Add("dateList", JsonConvert.SerializeObject(filterList));
                this.View.ShowForm(formpa, delegate (FormResult result)
                {
                    var rdata = result.ReturnData as DynamicObject;
                    if (rdata != null)
                    {
                        var v = rdata[0];
                        var name = rdata[1];
                        this.View.Model.SetValue("F_DateStr", v);
                        this.View.Model.SetValue("F_DateName", name);
                    }
                });
            }
            else
            {
                //获取报表过滤方案的构建基础，便于后续模型构建
                var rptFilterServiceProvider = rptFilterMetadata.BusinessInfo.GetForm().GetFormServiceProvider();
                var rptModel = new SysReportFilterModel();
                rptModel.SetContext(ctx, rptFilterMetadata.BusinessInfo, rptFilterServiceProvider);
                rptModel.FormId = rptFilterMetadata.BusinessInfo.GetForm().Id;
                rptModel.FilterObject.FilterMetaData = comFilterMetadata;
                rptModel.InitFieldList(rptMetadata, rptFilterMetadata);
                rptModel.GetSchemeList();
                //IsNullOrEmptyOrWhiteSpace()方法须using Kingdee.BOS.Util;
                if (rptFilterSchemeId.IsNullOrEmptyOrWhiteSpace())
                {
                    rptModel.LoadDefaultScheme();//加载默认过滤方案
                }
                else
                {
                    rptModel.Load(rptFilterSchemeId);
                }
                var filterPara = rptModel.GetFilterParameter();
                //报表参数
                IRptParams param = new RptParams();
                param.FormId = rptFilterMetadata.BusinessInfo.GetForm().Id;
                param.StartRow = 1;
                param.EndRow = int.MaxValue;
                param.FilterParameter = filterPara;
                param.FilterFieldInfo = rptModel.FilterFieldInfo;
                param.CustomParams = new Dictionary<string, object>();
                param.CustomParams.Add("OpenParameter", new Dictionary<string, object>());
                // param.CustomParams = rptModel.SchemeEntity.CustomFilterSetting;
                //报表服务参数，用于查询。
                var reportServiceParam = new ReportServiceParameter();
                reportServiceParam.RptFilterParams = param;
                reportServiceParam.Context = ctx;
                reportServiceParam.PageId = Guid.NewGuid().ToString();
                reportServiceParam.BusinessInfo = rptMetadata.BusinessInfo;

                var reportData = SysReportServiceHelper.GetReportData(reportServiceParam);
                var dataf = reportData.DataSource;
                List<DataColumn> filterList = new List<DataColumn>();
                foreach (DataColumn item in dataf.Columns)
                {
                    DataColumn col = new DataColumn();
                    col.ColumnName = item.ColumnName;
                    col.Caption = item.Caption;
                    filterList.Add(col);
                }
                DynamicFormShowParameter formpa = new DynamicFormShowParameter();
                formpa.FormId = "POSW_ReportDateList";
                formpa.CustomParams.Add("dateList", JsonConvert.SerializeObject(filterList));
                this.View.ShowForm(formpa, delegate (FormResult result)
                {
                    var rdata = result.ReturnData as DynamicObject;
                    if (rdata != null)
                    {
                        var v = rdata[0];
                        var name = rdata[1];
                        this.View.Model.SetValue("F_DateStr", v);
                        this.View.Model.SetValue("F_DateName", name);
                    }
                });
            }
        }

        private DynamicObject DeserializeCustomFilter(BusinessInfo businessInfo, string xml)
        {
            DcxmlBinder binder = new DynamicObjectDcxmlBinder(businessInfo);
            binder.OnlyDbProperty = false;
            DcxmlSerializer target = new DcxmlSerializer(binder);
            //切换到中性语言，获取主差量
            //CultureInfo inv = new CultureInfo(2052); //中性语言
            binder.Culture = CultureInfo.InvariantCulture;// inv;
                                                          // 集合忽略主键冲突
            target.ColloctionIgnorePKValue = true;
            DynamicObject obj = (DynamicObject)target.DeserializeFromString(xml, null);
            return obj;
        }

        private DataTable GetSqlRptData(Context ctx, FormMetadata rptMetadata, string rptFilterSchemeId)
        {
            DataTable dt = null;
            ISQLReportService service = ServiceFactory.GetSQLReportService(ctx);
            SQLFilterParameter filter = new SQLFilterParameter();
            SysReportForm form = rptMetadata.BusinessInfo.GetForm() as SysReportForm;
            try
            {
                List<FilterSettingItem> sqlKeyValue = new List<FilterSettingItem>();
                string xmlContent = GetxmlString(rptFilterSchemeId);
                // 第一步：XML 反序列化
                var xmlSerializer = new XmlSerializer(typeof(SQLFilterSchemeEntity));
                SQLFilterSchemeEntity entity;
                using (var reader = new StringReader(xmlContent))
                {
                    entity = (SQLFilterSchemeEntity)xmlSerializer.Deserialize(reader);
                }

                // 第二步：JSON 反序列化（关键修正点）
                sqlKeyValue = JsonConvert.DeserializeObject<List<FilterSettingItem>>(entity.SQLFilterSettingJson);
                foreach (var keyword in form.SQLDataSource.KeyWordList)
                {
                    SQLFilterField filterField = new SQLFilterField();
                    filterField.Caption = keyword.Name;
                    filterField.IsAllowInput = keyword.IsAllowInput;
                    filterField.IsMultiSelect = keyword.IsMultiSelect;
                    filterField.KeyWord = keyword.KeyWord;
                    foreach (var sqlr in sqlKeyValue)
                    {
                        if (sqlr.KeyWord == keyword.KeyWord)
                        {
                            SQLFilterRow filterRow = new SQLFilterRow(filterField, sqlr.Value, filterField.Caption, false);
                            filter.SQLFilterRows.Add(filterRow);
                        }
                    }
                }
                SqlReportQueryResult sqlReportQueryResult = service.CreateDirectSqlData(ctx, filter, form.SQLDataSource);

                if (sqlReportQueryResult.DataSource == null)
                {
                    if (sqlReportQueryResult.TableName.IsNullOrEmptyOrWhiteSpace() == false)
                    {
                        dt = DBUtils.ExecuteDataSet(ctx, string.Format("SELECT * FROM {0}", sqlReportQueryResult.TableName)).Tables[0];
                    }
                }
                else
                {
                    dt = sqlReportQueryResult.DataSource;
                }
            }
            catch (Exception ex) { }
            if (dt.Columns.Contains("FIDENTITYID"))
            {
                dt.Columns.Remove("FIDENTITYID");
            }
            return dt;
        }

        /// <summary>
        /// 选择过滤方案并返回
        /// </summary>
        /// <param name="row"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void ShowAndFillFilter(int row, string formId)
        {
            DynamicFormShowParameter formpa = new DynamicFormShowParameter();
            formpa.FormId = "POSW_FilterList";
            formpa.CustomParams.Add("formId", formId);
            this.View.ShowForm(formpa, delegate (FormResult result)
            {
                var rdata = result.ReturnData as DynamicObject;
                if (rdata != null)
                {
                    var v = rdata[1];
                    this.View.Model.SetValue("F_POSW_Filter", v);
                }
            });
        }

        //public override void BeforeFilterGridF7Select(BeforeFilterGridF7SelectEventArgs e)
        //{
        //    base.BeforeFilterGridF7Select(e);
        //}
        //public override void AuthPermissionBeforeF7Select(AuthPermissionBeforeF7SelectEventArgs e)
        //{
        //    base.AuthPermissionBeforeF7Select(e);
        //}
    }
}
